package com.example.wiki.interceptor;// package com.jiawa.wiki.interceptor;

 import com.alibaba.fastjson.JSON;
 import com.example.wiki.resp.UserLoginResp;
 import com.example.wiki.utils.LoginUserContext;
 import com.mysql.cj.log.Log;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Component;
 import org.springframework.web.servlet.HandlerInterceptor;
 import org.springframework.web.servlet.ModelAndView;

 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;

 /**
  * 拦截器：Spring框架特有的，常用于登录校验，权限校验，请求日志打印 /login
  */
 @Component
 public class LogInterceptor implements HandlerInterceptor {

     private static final Logger LOG = LoggerFactory.getLogger(LogInterceptor.class);

     @Resource
     private RedisTemplate redisTemplate;

     @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
         // 打印请求信息
         LOG.info("------------- LogInterceptor 开始 -------------");
         long startTime =System.currentTimeMillis();
         request.setAttribute("requestStartTime", startTime);


         if(request.getMethod().toUpperCase().equals("OPTIONS")){
             return true;
         }
         String Path =request.getRequestURI().toString();
         LOG.info("接口登录拦截:path{}",Path);

         //获取header的token参数
         String token = request.getHeader("Authorization");
         if(token!=null && token.startsWith("Bearer ")){
             // 使用substring方法去掉"Bearer "部分
             //返回此字符串的子字符串。子字符串以指定索引处的字符开头，并延伸到此字符串的末尾。
             token =token.substring(7);
         }

         LOG.info("登录校验开始，token：{}", token);

         if(token== null || token.isEmpty()){
             response.setStatus(HttpStatus.UNAUTHORIZED.value());
             return false;

         }
//   opsForValue(): 这是RedisTemplate的一个方法，用于获取一个操作字符串值（即简单key-value对）的ValueOperations对象。
//    ValueOperations接口提供了对Redis字符串类型数据的操作方法，比如get, set, increment等。
         Object object = redisTemplate.opsForValue().get(token);
         if(object ==null){
             LOG.warn("token无效,请求被拦截");
             response.setStatus(HttpStatus.UNAUTHORIZED.value());
             return false;
         }else {
             LOG.info(("token有效,请求放行"));
             LoginUserContext.setUser(JSON.parseObject((String) object, UserLoginResp.class));
             return true;
         }
     }

     @Override
     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
         long startTime = (Long) request.getAttribute("requestStartTime");
         LOG.info("------------- LogInterceptor 结束 耗时：{} ms -------------", System.currentTimeMillis() - startTime);
     }
 }
